#include "walls.h"
#include "textures.h"
#include "mtxlib.h"

using namespace Textures;

namespace Walls
{

void draw_ceiling()
{
	glColor4f(0,0,1,1);
	glBegin(GL_QUADS);
			glNormal3f(0,0,-1);
			glVertex3f(-2,-2,2);
			glVertex3f(2,-2,2);
			glVertex3f(2,2,2);
			glVertex3f(-2,2,2);	
	glEnd();
	glBindTexture(GL_TEXTURE_2D, tex_perlin);
	glEnable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GEQUAL, .6f);
	glColor4f(1,1,1,1);
	glBegin(GL_QUADS);
			glNormal3f(0,0,-1);
			glMultiTexCoord2f(GL_TEXTURE0, 0,0);
			glVertex3f(-2,-2,2);
			glMultiTexCoord2f(GL_TEXTURE0, 1,0);
			glVertex3f(2,-2,2);
			glMultiTexCoord2f(GL_TEXTURE0, 1,1);
			glVertex3f(2,2,2);
			glMultiTexCoord2f(GL_TEXTURE0, 0,1);
			glVertex3f(-2,2,2);	
	glEnd();
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_ALPHA_TEST);
}

void draw_floor()
{
	glActiveTexture(GL_TEXTURE0);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex_wood);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	glBegin(GL_QUADS);
			glNormal3f(0,0,1);
			glTexCoord2f(0,1);
			glVertex3f(-2,2,-2);
			glTexCoord2f(1,1);
			glVertex3f(2,2,-2);
			glTexCoord2f(1,0);
			glVertex3f(2,-2,-2);
			glTexCoord2f(0,0);
			glVertex3f(-2,-2,-2);
	glEnd();
	glDisable(GL_TEXTURE_2D);
}

void draw_3_walls()
{

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex_bricks);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	vector4 v[2];
	v[0] = vector4(.25f,.25f,0,0);
	v[1] = vector4(0,0,.25f,0);
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGenfv(GL_S, GL_OBJECT_PLANE, (float*)&(v[0]));
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGenfv(GL_T, GL_OBJECT_PLANE, (float*)&(v[1]));
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glBegin(GL_QUADS);
			glNormal3f(0,1,0);
			glVertex3f(2,-2,-2);
			glVertex3f(2,-2,2);
			glVertex3f(-2,-2,2);
			glVertex3f(-2,-2,-2);
			glNormal3f(1,0,0);
			glVertex3f(-2,2,2);
			glVertex3f(-2,2,-2);
			glVertex3f(-2,-2,-2);
			glVertex3f(-2,-2,2);
			glNormal3f(-1, 0, 0);
			glVertex3f(2,-2,2);
			glVertex3f(2,-2,-2);
			glVertex3f(2,2,-2);
			glVertex3f(2,2,2);
	glEnd();
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_2D);
}

void draw_back_wall()
{
	glActiveTexture(GL_TEXTURE0);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, Textures::lod_bias);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex_bricks);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	vector4 v[2];
	v[0] = vector4(.25f,.25f,0,0);
	v[1] = vector4(0,0,.25f,0);
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGenfv(GL_S, GL_OBJECT_PLANE, (float*)&(v[0]));
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGenfv(GL_T, GL_OBJECT_PLANE, (float*)&(v[1]));
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);

	glActiveTexture(GL_TEXTURE1); // poster
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glPushMatrix();

	glTranslatef(0.f, 0.5f, 0.f);
	glTranslatef(0.5f, 0.0f, 0.f);
	static float xScale = 4.0f;
	static float yScale = 3.0f;
	glRotatef(-10.0f, 0.0f, 0.0f, -1.0f);
	glScalef(xScale, yScale, 1.0f);
	
	glTranslatef(-0.3f, -0.5f, 0.f);

	glEnable(GL_TEXTURE_2D);
	

	glBindTexture(GL_TEXTURE_2D, tex_poster);
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, Textures::lod_bias);
	vector4 border = vector4(.0f,.0f,.0f,.0f);
	glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR,(float*)&border.x);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);

	 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);   //Interpolate RGB with RGB
	 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
	 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
	 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE);
	 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
	 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
	 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
	
	//v[0] = vector4(.25f,.25f,0,0);
	//v[1] = vector4(0,0, -.25f,0);
	//glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	//glTexGenfv(GL_S, GL_OBJECT_PLANE, (float*)&(v[0]));
	//glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	//glTexGenfv(GL_T, GL_OBJECT_PLANE, (float*)&(v[1]));
	//glEnable(GL_TEXTURE_GEN_S);
	//glEnable(GL_TEXTURE_GEN_T);
	glBegin(GL_QUADS);
			glNormal3f(0,-1,0);
			// lower left corner
			glMultiTexCoord2f(GL_TEXTURE1,0,1);
			glVertex3f(-2,2,-2);
			
			// upper left corner
			glMultiTexCoord2f(GL_TEXTURE1,0,0);
			glVertex3f(-2,2,2);
			
			// upper right corner
			glMultiTexCoord2f(GL_TEXTURE1,1,0);
			glVertex3f(2,2,2);
			
			// lower right corner
			glMultiTexCoord2f(GL_TEXTURE1,1,1);
			glVertex3f(2,2,-2);
	glEnd();

	// disable poster texture
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glDisable(GL_TEXTURE_2D);
	//glDisable(GL_TEXTURE_GEN_S);
	//glDisable(GL_TEXTURE_GEN_T);
	//glDisable(GL_TEXTURE_2D);

	// disable wall texture
	glActiveTexture(GL_TEXTURE0);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_2D);

	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glActiveTexture(GL_TEXTURE0);
}

void draw_box()
{
	glCullFace(GL_FRONT);

	draw_floor();
	draw_ceiling();
	draw_3_walls();
	draw_back_wall();

	glCullFace(GL_BACK);
}

}